#pragma once
#include <vector>
#include <lua/lua.hpp>
#include <glm/glm.hpp>

namespace sg {
	class lua_mgr {
	private:
		lua_State *_L;

	public:
		lua_mgr() 
			: _L(NULL){

		}

		~lua_mgr() {
			lua_close(_L);
		}

		void 
		init() {
			_L = luaL_newstate();
			luaL_openlibs(_L);
		}

		void
		getpoints(std::vector<glm::vec3> &vertices) {
			vertices.clear();
			lua_State *L = _L;

			do {
				const char *filename = "./call.lua";
				if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)) {
					printf("fail to load config, error:%s\n", lua_tostring(L, -1));
					break;
				}

				const char *funcname = "getpoints";
				lua_getglobal(L, funcname);

				if (lua_pcall(L, 0, 1, 0) != LUA_OK) {
					printf("fail to call func:%s, error:%s\n", funcname, lua_tostring(L, -1));
					break;
				}

				if (!lua_istable(L, -1)) {
					printf("the returned result is not a table\n");
					break;
				}

				lua_len(L, -1);
				int len = lua_tointeger(L, -1);
				lua_pop(L, 1);
				printf("the returned points num:%d\n", len);
				for (int i = 1; i <= len; i++) {
					lua_rawgeti(L, -1, i);

					// 获取 {x = 1.0, y = 1.0, z = 1.0}
					int isnum;
					glm::vec3 v;
					lua_getfield(L, -1, "x");
					v.x = (float)lua_tonumberx(L, -1, &isnum);
					if (!isnum) {
						printf("invalid coordinate.x at index:%d\n", i);
						break;		
					}
					lua_pop(L, 1);

					lua_getfield(L, -1, "y");
					v.y = (float)lua_tonumberx(L, -1, &isnum);
					if (!isnum) {
						printf("invalid coordinate.y at index:%d\n", i);
						break;		
					}
					lua_pop(L, 1);

					lua_getfield(L, -1, "z");
					v.z = (float)lua_tonumberx(L, -1, &isnum);
					if (!isnum) {
						printf("invalid coordinate.z at index:%d\n", i);
						break;		
					}
					lua_pop(L, 1);
					lua_pop(L, 1);

					vertices.push_back(v);
				}
			} while (false);

			lua_settop(L, 0);
		}
	};
}
